class AsyncSeriesHook {
    events = [];
    promiseEvents = [];

    constructor() {
        console.log('AsyncSeriesHook');
    }

    tapAsync(name, cb) {
        cb = typeof cb === 'function' ? cb : (...args) => args;
        this.events.push(cb);
    }

    tapPromise(name, cb) {
        cb = typeof cb === 'function' ? cb : (...args) => args;
        this.promiseEvents.push(cb);
    }

    callAsync(...args) {
        const callAsyncEvent = args.pop();
        const event = this.events.shift();
        const next = () => {
            if (this.events.length === 0) {
                callAsyncEvent && callAsyncEvent();
                return;
            }
            this.events.shift()(...args, next);
        }
        event(...args, next);
    }

    promise(...args) {
        return this.promiseEvents.reduce((fn1, fn2) => {
            return (...args1) => {
                return fn1(...args1).then(() => fn2(...args1));
            }
        })(...args);
    }
}

module.exports = AsyncSeriesHook;